package com.cgs.query.handler.statement

import com.cgs.query.configuration.QueryConfiguration
import com.cgs.query.domain.BoundSql
import com.cgs.query.domain.StatementType
import com.cgs.query.executor.ExecutionContext
import com.cgs.query.handler.StatementHandler
import java.sql.Connection
import java.sql.Statement
import mu.KotlinLogging

private val logger = KotlinLogging.logger { }

/**路由选择：sql执行：预编译jdbc*/
class RoutingStatementHandler(
        config: QueryConfiguration,
        executionContext: ExecutionContext) : StatementHandler {

    override val boundSql: BoundSql
        get() = this.delegate.boundSql

    override val parameterHandler = config.parameterHandler
    private val printSql = config.configProperties.printSql
    private val delegate: StatementHandler

    init {
        when (executionContext.mappedStatement.statementType) {
            StatementType.PREPARED -> this.delegate = PreparedStatementHandler(config, executionContext)
            StatementType.STATEMENT -> this.delegate = SimpleStatementHandler(config, executionContext)
            StatementType.CALLABLE -> this.delegate = CallableStatementHandler(config, executionContext)
            StatementType.SCRIPT -> this.delegate = ScriptStatementHandler(config, executionContext)
            StatementType.PAGINATION -> this.delegate = PaginationStatementHandler(config, executionContext)
        }
    }

    override fun prepare(connection: Connection): Statement {
        return delegate.prepare(connection)
    }

    override fun parameterize(statement: Statement) {
        delegate.parameterize(statement)
    }

    override fun update(statement: Statement): Int {
        if (printSql) {
            logger.info { "SQL[${delegate.boundSql}]" }
        }
        return delegate.update(statement)
    }

    override fun query(statement: Statement): List<Any> {
        if (printSql) {
            logger.info { "SQL[${delegate.boundSql}]" }
        }
        return delegate.query(statement)
    }

    override fun close(statement: Statement?) {
        delegate.close(statement)
    }

    override fun execute(statement: Statement): List<Any> {
        if (printSql) {
            logger.info { "SQL[${delegate.boundSql}]" }
        }
        return delegate.execute(statement)
    }
}
